package Test;

//通过Singleton这个类来实现单例模式，保证Singleton这个类只是唯一实例
//饿汉模式
class Singleton{
    //1.使用static创建一个实例，并且立即进行实例化
    //   这个instance对应的实例，就是该类的唯一实例
    private static Singleton instance = new Singleton();
    //2.为了防止程序员在其他地方不小心的new这个Singleton，就可以把构造方法设为private
    private Singleton(){

    }
    //3.提供一个方法，让外面能够拿到唯一实例
    public static Singleton getInstance(){
        return instance;
    }

}
//懒汉模式
class Singleton1 {
    private static Singleton1 instance = null;
    private Singleton1() {}
    public static Singleton1 getInstance() {
        if (instance == null) {
            instance = new Singleton1();
        }
        return instance;
    }
}
/*
线程安全问题发生在首次创建实例时. 如果在多个线程中同时调用 getInstance 方法, 就可能导致
创建出多个实例.
一旦实例已经创建好了, 后面再多线程环境调用 getInstance 就不再有线程安全问题了(不再修改
instance 了)
加上 synchronized 可以改善这里的线程安全问题
* */
class Singleton2 {
    private static Singleton2 instance = null;
    private Singleton2() {}
    public synchronized static Singleton2 getInstance() {
        if (instance == null) {
        instance = new Singleton2();
        }
        return instance;
    }
}
/*
* 使用双重 if 判定, 降低锁竞争的频率.
给 instance 加上了 volatile.
* */
class Singleton3 {
    private static volatile Singleton3 instance = null;
    private Singleton3() {}
    public static Singleton3 getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton3();
                }
            }
        }
        return instance;
    }
}
public class Test10 {
    public static void main(String[] args) {
        Singleton instance = Singleton.getInstance();
    }
}
